var {
    Cmd,
    Tcm_Casino_CreateGame,
    Tsm_Casino_CreateGame,
    Tcm_Casino_Join,
    Tsm_Casino_Join,
    Tcm_Casino_SitDown,
    Tsm_Casino_SitDown,
    Tsm_Casino_ChangeUserState,
    Tsm_Casino_ChangePlayerInfoVo,
    Tcm_Casino_Action,
    Tsm_Casino_Action,
    Tsm_Casino_ChangeAction,
    Tsm_Casino_OpenAction,
    Tsm_Casino_ChangePlayerCard,
    Tsm_Casino_ChangePlayerCardList,
    Tsm_Casino_ChangeRoomCard,
    Tsm_Casino_ChangeRoomCardList,
    Tcm_Casino_StandUp,
    Tsm_Casino_StandUp,
    Tcm_Casino_Bet,
    Tsm_Casino_Bet,
    Tcm_Casino_Reward,
    Tsm_Casino_Reward
} = require("CasinoProtocol")

var {CmdType} = require("Protocol")
var {GatewayType} = require("FrontProtocol")
var {
    Tcm_Gateway_GetFrontend,
    Tsm_Gateway_GetFrontend
} = require("FrontProtocol")
var {
    User_None,
    User_LoginByUid,
    User_LoginByCode,
    Tcm_User_LoginByUid,
    Tcm_User_LoginByCode,
    Tsm_User_Login
} = require("UserProtocol")


const IO_RECV = "io-recv"
const IO_SEND = "io-send"

//const URL = "ws://192.168.0.75:13101"
const URL = "ws://120.92.76.235:13101"

const HEAD_LEN = 48
const CMDTYPE_OFFSET = 2
const CMD_OFFSET = 3
const BUFMARK = 0xA13B
const BUFCODE1 = 0x3ABA
const BUFCODE2 = 0x413C


cc.Class({
    extends: cc.Component,
    io: null,
    handle: cc.Node, //需要处理的逻辑节点，所有的消息都将反馈到此节点
    isGateway: false,
    onLoad() {
        this.connect()
    },

    connect(url = URL) {
        if (this.io) this.io.close()
        this.io = new WebSocket(url)
        this.io.onopen = (e) => {
            console.log("连接上服务器")
            if (!this.isGateway)
                this.gateway({uid: this.handle.gameUid()})
            else {
                this.handle.didConnectServer()
            }

        }
        this.io.onmessage = (e) => {
            console.log("收到数据")
            var fileReader = new FileReader()
            fileReader.onload = () => {
                let buffer = Buffer.from(fileReader.result)
                let cmdType = buffer.readUInt8(CMDTYPE_OFFSET)
                let cmd = buffer.readUInt8(CMD_OFFSET)
                let body = buffer.slice(HEAD_LEN)
                this.recvMessage(cmdType, cmd, body)
            }
            fileReader.readAsArrayBuffer(e.data)

        }
        this.io.onerror = (e) => {
            console.log(e)
            if (this.handle.error) {
                this.handle.error(e)
            }
        }
    },

    /**
     * 接受到消息
     * @param cmdType 命令类型
     * @param cmd     动作类型
     * @param buffer  接受到的数据 属于buffer 需要手动解析
     */
    recvMessage(cmdType, cmd, buffer) {
        let obj = null
        switch (cmdType) {
            case CmdType.CmdType_Gateway:
                obj = this.decodeGateway(buffer)
                break
            case CmdType.CmdType_Casino:
                switch (cmd) {
                    case Cmd.Casino_Join:
                        obj = this.decodeJoin(buffer)
                        break
                    case Cmd.Casino_CreateGame:
                        obj = this.decodeCreateGame(buffer)
                        break
                    case Cmd.Casino_ChangeAction:
                        obj = this.decodeChangeAction(buffer)
                        break
                    case Cmd.Casino_SitDown:
                        obj = this.decodeSit(buffer)
                        break
                    case Cmd.Casino_StandUp:
                        obj = this.decodeStandUp(buffer)
                        break
                    case Cmd.Casino_ChangeUserState:
                        obj = this.decodeChangeUserState(buffer)
                        break
                    case Cmd.Casino_ChangePlayerInfoVo:
                        obj = this.decodeChangePlayerInfoVo(buffer)
                        break
                    case Cmd.Casino_Action:
                        obj = this.decodeActoin(buffer)
                        break
                    case Cmd.Casino_OpenAction:
                        obj = this.decodeOpenAction(buffer)
                        break
                    case Cmd.Casino_CloseAction:
                        obj = this.decodeCloseAction(buffer)
                        break
                    case Cmd.Casino_Bet:
                        obj = this.decodeBet(buffer)
                        break
                    case Cmd.Casino_BeginRound:
                        obj = this.decodeBeginRound(buffer)
                        break
                    case Cmd.Casino_ChangePlayerCard:
                        obj = this.decodeChangePlayerCard(buffer)
                        break
                    case Cmd.Casino_ChangePlayerCardList:
                        obj = this.decodeChangePlayerCardList(buffer)
                        break
                    case Cmd.Casino_ChangeRoomCard:
                        obj = this.decodeChangeRoomCard(buffer)
                        break
                    case Cmd.Casino_ChangeRoomCardList:
                        obj = this.decodeChangeRoomCardList(buffer)
                        break
                    case Cmd.Casino_Result:
                        break
                    default:
                        break
                }
                break
            case CmdType.CmdType_User:
                obj = this.decodeLogin(buffer)
                break
            default: {
                break
            }
        }
        console.log("--------> " + cmdType + " " + cmd)
        console.log(obj)
        this.handle.finishRecvMessage()
        window.sock.node.emit(cmdType + "-" + cmd, obj)
    },


    close() {

    },

    /**
     * 获取网关
     * @param Tcm_Gateway_GetFrontend
     */
    gateway(obj) {
        this.compactAndSend(CmdType.CmdType_Gateway, GatewayType.Gateway_GetFrontend, new Tcm_Gateway_GetFrontend(obj).toBuffer())
    },

    decodeGateway(buffer) {
        this.isGateway = true
        return new Tsm_Gateway_GetFrontend(buffer)
    },

    /**
     *
     * @param obj:ITcm_User_LoginByUid | ITcm_User_LoginByCode
     */
    login(obj) {
        let data = null
        let {type} = obj
        switch (type) {
            case User_LoginByUid:
                data = new Tcm_User_LoginByUid(obj).toBuffer()
                break
            default:
                data = new Tcm_User_LoginByCode(obj).toBuffer()
                break
        }
        this.compactAndSend(CmdType.CmdType_User, type, data)
    },

    decodeLogin(buffer) {
        return new Tsm_User_Login(buffer)
    },

    /**
     * 加入房间
     */
    decodeJoin(buffer) {
        return new Tsm_Casino_Join(buffer)
    },

    /**
     * 创建房间
     * obj = Tcm_Casino_CreateGame
     */
    createGame(obj) {
        this.compactAndSend(CmdType.CmdType_Casino, Cmd.Casino_CreateGame, new Tcm_Casino_CreateGame(obj).toBuffer())
    },

    decodeCreateGame(obj) {
        return new Tsm_Casino_CreateGame(obj)
    },

    /**
     * 加入房间
     * @param Tcm_Casino_Join
     */
    join(obj) {
        this.compactAndSend(CmdType.CmdType_Casino, Cmd.Casino_Join, new Tcm_Casino_Join(obj).toBuffer())
    },

    decodeJoin(buffer) {
        return new Tsm_Casino_Join(buffer)
    },

    /**
     * 坐下
     * @param {Tcm_Casino_SitDown}
     */
    sit(obj) {
        this.compactAndSend(CmdType.CmdType_Casino, Cmd.Casino_SitDown, new Tcm_Casino_SitDown(obj).toBuffer())
    },

    decodeSit(buffer) {
        return new Tsm_Casino_SitDown(buffer)
    },

    /**
     * 站起
     * @param {Tcm_Casino_StandUp}
     */
    standUp(obj) {
        this.compactAndSend(CmdType.CmdType_Casino, Cmd.Casino_StandUp, new Tcm_Casino_StandUp(obj).toBuffer())
    },

    decodeStandUp(buffer) {
        return new Tsm_Casino_StandUp(buffer)
    },

    decodeChangeUserState(buffer){
        return new Tsm_Casino_ChangeUserState(buffer)
    },

    decodeBeginRound(){
        console.log("BeginRound")
        return null
    },

    /**
     * 房间玩家信息发生改变
     */
    decodeChangePlayerInfoVo(buffer){
        return new Tsm_Casino_ChangePlayerInfoVo(buffer)
    },

    /**
     * 房间状态发生改变 (主播按钮离开，开牌之间切换)
     */
    decodeChangeAction(buffer) {
        return new Tsm_Casino_ChangeAction(buffer)
    },

    /**
     * 动作
     * @param Tcm_Casino_Action
     */
    action(obj) {
        this.compactAndSend(CmdType.CmdType_Casino, Cmd.Casino_Action, new Tcm_Casino_Action(obj).toBuffer())
    },

    decodeActoin(buffer) {
        return new Tsm_Casino_Action(buffer)
    },

    /**
     * 打开面板
     * @param buffer
     * @returns {*}
     */
    decodeOpenAction(buffer){
        return new Tsm_Casino_OpenAction(buffer)
    },

    /**
     * 关闭面板
     * @param buffer
     * @returns {null}
     */
    decodeCloseAction(buffer){
        console.log("CloseAction")
        return null
    },

    /**
     * 改变玩家的牌
     */
    decodeChangePlayerCard(buffer){
        return new Tsm_Casino_ChangePlayerCard(buffer)
    },

    decodeChangePlayerCardList(buffer){
        return new Tsm_Casino_ChangePlayerCardList(buffer)
    },

    /**
     * 改变房间牌
     */
    decodeChangeRoomCard(buffer){
        return new Tsm_Casino_ChangeRoomCard(buffer)
    },

    /**
     * 改变房间卡牌列表
     * @param buffer
     */
    decodeChangeRoomCardList(buffer){
        return new Tsm_Casino_ChangeRoomCardList(buffer)
    },


    /**
     *
     * @param {Tcm_Casino_Reward}
     */
    reword(obj) {
        this.compactAndSend(CmdType.CmdType_Casino, Cmd.Casino_Reward, new Tcm_Casino_Reward(obj).toBuffer())
    },

    decodeReword() {
        return new Tsm_Casino_Reward(buffer)
    },

    /**
     * 游戏开始
     * @param obj
     */
    startGame(obj) {
        this.compactAndSend(CmdType.CmdType_Casino, Cmd.Casino_BeginRound, null)
    },

    /**
     * 退出游戏
     * @param {Tcm_Casino_Quit}
     */
    quit(obj) {
        this.compactAndSend(CmdType.CmdType_Casino, Cmd.Casino_Quit, new Tcm_Casino_Quit(obj).toBuffer())
    },

    /**
     * 押注
     * @param {Tcm_Casino_Bet}
     */
    bet(obj) {
        this.compactAndSend(CmdType.CmdType_Casino, Cmd.Casino_Bet, new Tcm_Casino_Bet(obj).toBuffer())
    },

    decodeBet(buffer) {
        return new Tsm_Casino_Bet(buffer)
    },

    reward(obj) {
        this.compactAndSend(CmdType.CmdType_Casino, Cmd.Casino_Reward, new Tcm_Casino_Reward(obj))
    },

    decodeReward(buffer) {
        return new Tsm_Casino_Reward(buffer)
    },

    /**
     *
     * @param cmdType
     * @param cmd
     * @param data 内容
     * @returns {*}
     */
    compactAndSend(cmdType, cmd, data) {
        let total = HEAD_LEN + data.byteLength
        let buffer = Buffer.allocUnsafe(total)
        buffer.writeUInt16LE(total)
        buffer.writeUInt8(cmdType, 2)
        buffer.writeUInt8(cmd, 3)
        buffer.writeUInt16LE(BUFMARK, 4)
        buffer.writeUInt32LE((total ^ BUFCODE1) & BUFCODE2, 6)
        if (data) {
            for (let i = 0; i < data.byteLength; i++) {
                buffer[HEAD_LEN + i] = data[i]
            }
        }
        this.handle.beforeSend()
        console.log("发送消息", cmdType, cmd, total)
        this.io.send(buffer)
    },
})